/// @file ui_ao.cpp
/// @brief Implementation of the UiAo class
/// 
/// This file implements the UiAo class which handles user interface interactions
/// and communicates with the AuthAo through events.

#include "ui_ao.h"
#include "auth_ao.h"
#include "auth_events.h"
#include "spdlog/spdlog.h"
#include <cstdint>

namespace {
    Q_DEFINE_THIS_FILE
}

// Global instance of the UiAo
UiAo* const the_AO_Ui = new UiAo();

UiAo::UiAo()
    : QActive(initial)
{
    // 不在构造函数中调用 spdlog，避免初始化时的问题
}

Q_STATE_DEF(UiAo, initial) {
    Q_UNUSED_PAR(e);
    
    // Subscribe to authentication response events
    subscribe(LOGIN_RESPONSE_SUCCESS_SIG);
    subscribe(LOGIN_RESPONSE_FAILURE_SIG);
    subscribe(REGISTER_RESPONSE_SUCCESS_SIG);
    subscribe(REGISTER_RESPONSE_FAILURE_SIG);
    subscribe(LOGOUT_RESPONSE_SUCCESS_SIG);
    subscribe(LOGOUT_RESPONSE_FAILURE_SIG);
    subscribe(SESSION_STATUS_AUTHENTICATED_SIG);
    subscribe(SESSION_STATUS_UNAUTHENTICATED_SIG);
    
    return tran(&processing);
}

Q_STATE_DEF(UiAo, processing) {
    QP::QState status_;
    switch (e->sig) {
        case LOGIN_REQUEST_SIG: {
            const LoginRequestEvt* loginEvt = Q_EVT_CAST(LoginRequestEvt);
            spdlog::info("UI AO: Processing login request for user '{}'", loginEvt->username);
            
            // Forward to Auth AO
#ifdef QEVT_PAR_INIT
            LoginRequestEvt* forwardEvt = Q_NEW(LoginRequestEvt, LOGIN_REQUEST_SIG, loginEvt->username, loginEvt->password);
#else
            LoginRequestEvt* forwardEvt = Q_NEW(LoginRequestEvt, LOGIN_REQUEST_SIG);
            forwardEvt->username = loginEvt->username;
            forwardEvt->password = loginEvt->password;
#endif
            the_AO_Auth->POST(forwardEvt, this);
            
            status_ = tran(&handlingLoginResponse);
            break;
        }
        case REGISTER_REQUEST_SIG: {
            const RegisterRequestEvt* registerEvt = Q_EVT_CAST(RegisterRequestEvt);
            spdlog::info("UI AO: Processing register request for user '{}'", registerEvt->username);
            
            // Forward to Auth AO
#ifdef QEVT_PAR_INIT
            RegisterRequestEvt* forwardEvt = Q_NEW(RegisterRequestEvt, REGISTER_REQUEST_SIG, registerEvt->username, registerEvt->password);
#else
            RegisterRequestEvt* forwardEvt = Q_NEW(RegisterRequestEvt, REGISTER_REQUEST_SIG);
            forwardEvt->username = registerEvt->username;
            forwardEvt->password = registerEvt->password;
#endif
            the_AO_Auth->POST(forwardEvt, this);
            
            status_ = tran(&handlingRegisterResponse);
            break;
        }
        case LOGOUT_REQUEST_SIG: {
            const LogoutRequestEvt* logoutEvt = Q_EVT_CAST(LogoutRequestEvt);
            spdlog::info("UI AO: Processing logout request for user ID {}", logoutEvt->user_id);
            
            // Forward to Auth AO
#ifdef QEVT_PAR_INIT
            LogoutRequestEvt* forwardEvt = Q_NEW(LogoutRequestEvt, LOGOUT_REQUEST_SIG, logoutEvt->user_id);
#else
            LogoutRequestEvt* forwardEvt = Q_NEW(LogoutRequestEvt, LOGOUT_REQUEST_SIG);
            forwardEvt->user_id = logoutEvt->user_id;
#endif
            the_AO_Auth->POST(forwardEvt, this);
            
            status_ = tran(&handlingLogoutResponse);
            break;
        }
        case SESSION_CHECK_REQUEST_SIG: {
            const SessionCheckRequestEvt* sessionCheckEvt = Q_EVT_CAST(SessionCheckRequestEvt);
            spdlog::info("UI AO: Processing session check request for session '{}'", sessionCheckEvt->session_id);
            
            // Forward to Auth AO
#ifdef QEVT_PAR_INIT
            SessionCheckRequestEvt* forwardEvt = Q_NEW(SessionCheckRequestEvt, SESSION_CHECK_REQUEST_SIG, sessionCheckEvt->session_id);
#else
            SessionCheckRequestEvt* forwardEvt = Q_NEW(SessionCheckRequestEvt, SESSION_CHECK_REQUEST_SIG);
            forwardEvt->session_id = sessionCheckEvt->session_id;
#endif
            the_AO_Auth->POST(forwardEvt, this);
            
            status_ = tran(&handlingSessionCheckResponse);
            break;
        }
        default: {
            status_ = super(&top);
            break;
        }
    }
    return status_;
}

Q_STATE_DEF(UiAo, handlingLoginResponse) {
    QP::QState status_;
    switch (e->sig) {
        case LOGIN_RESPONSE_SUCCESS_SIG: {
            spdlog::info("UI AO: Received login success response");
            status_ = tran(&processing);
            break;
        }
        case LOGIN_RESPONSE_FAILURE_SIG: {
            spdlog::info("UI AO: Received login failure response");
            status_ = tran(&processing);
            break;
        }
        default: {
            status_ = super(&processing);
            break;
        }
    }
    return status_;
}

Q_STATE_DEF(UiAo, handlingRegisterResponse) {
    QP::QState status_;
    switch (e->sig) {
        case REGISTER_RESPONSE_SUCCESS_SIG: {
            spdlog::info("UI AO: Received register success response");
            status_ = tran(&processing);
            break;
        }
        case REGISTER_RESPONSE_FAILURE_SIG: {
            spdlog::info("UI AO: Received register failure response");
            status_ = tran(&processing);
            break;
        }
        default: {
            status_ = super(&processing);
            break;
        }
    }
    return status_;
}

Q_STATE_DEF(UiAo, handlingLogoutResponse) {
    QP::QState status_;
    switch (e->sig) {
        case LOGOUT_RESPONSE_SUCCESS_SIG: {
            spdlog::info("UI AO: Received logout success response");
            status_ = tran(&processing);
            break;
        }
        case LOGOUT_RESPONSE_FAILURE_SIG: {
            spdlog::info("UI AO: Received logout failure response");
            status_ = tran(&processing);
            break;
        }
        default: {
            status_ = super(&processing);
            break;
        }
    }
    return status_;
}

Q_STATE_DEF(UiAo, handlingSessionCheckResponse) {
    QP::QState status_;
    switch (e->sig) {
        case SESSION_STATUS_AUTHENTICATED_SIG: {
            spdlog::info("UI AO: Received session authenticated response");
            status_ = tran(&processing);
            break;
        }
        case SESSION_STATUS_UNAUTHENTICATED_SIG: {
            spdlog::info("UI AO: Received session unauthenticated response");
            status_ = tran(&processing);
            break;
        }
        default: {
            status_ = super(&processing);
            break;
        }
    }
    return status_;
}